pub mod function_keys;
mod read_file;
mod tool_result;
pub mod tools_model;
mod write_file;

use crate::models::ProjectConfig;
use anyhow::{anyhow, Result};
use function_keys::{READ_FILE_KEY, WRITE_FILE_KEY};
use serde::Deserialize;
use tools_model::{ReadFileArgs, ToolResult, WriteFileArgs};

#[derive(Debug, Deserialize)]
pub struct FunctionCallContext {
    pub id: String,
    pub name: String,
    pub arguments: String,
}
pub async fn dispatch_function_call(
    function_call_context: &FunctionCallContext,
    context: &Option<ProjectConfig>,
) -> Result<ToolResult> {
    match function_call_context.name.as_str() {
        READ_FILE_KEY => {
            if let Some(project_config) = context {
                let mut args =
                    serde_json::from_str::<ReadFileArgs>(&function_call_context.arguments)
                        .map_err(|e| anyhow!("Failed to parse read_file arguments: {}", e))?;

                args.call_id = Some(function_call_context.id.clone());
                args.name = Some(function_call_context.name.clone());
                read_file::read_file(&args, &project_config)
            } else {
                Err(anyhow!("正在尝试调用:{}，但是并未发现项目的配置文件，请参考cli_assistant的README.md，配置项目的config.yml", function_call_context.name))
            }
        }
        WRITE_FILE_KEY => {
            if let Some(project_config) = context {
                let mut args =
                    serde_json::from_str::<WriteFileArgs>(&function_call_context.arguments)
                        .map_err(|e| anyhow!("Failed to parse write_file arguments: {}", e))?;

                args.call_id = Some(function_call_context.id.clone());
                args.name = Some(function_call_context.name.clone());
                write_file::write_file(&args, &project_config)
            } else {
                Err(anyhow!("正在尝试调用:{}，但是并未发现项目的配置文件，请参考cli_assistant的README.md，配置项目的config.yml", function_call_context.name))
            }
        }
        _ => Err(anyhow!(
            "Unknown function call: {}",
            function_call_context.name
        )),
    }
}
